Spring笔记(3):IOC容器 |
您所在的位置:网站首页 › spring 重新注入 › Spring笔记(3):IOC容器 |
1、IOC容器是什么? IOC容器是Spring容器的重要组成部分,它具有依赖注入功能,负责实例化、定位、配置Bean对象,并建立对象之间依赖。 通过配置(Metadata),由Spring容器创建对象,这个配置是对应POJO对象类的属性进行注入,创建完毕后发送给ApplicationContext容器进行渲染。 2、两种Spring常见IOC容器 Spring BeanFactory容器:是一种最简单的容器,通过BeanFactory接口定义。 Spring Application容器:是一种企业级容器,通过ApplicationContext接口定义 因为ApplicationContext容器包括BeanFactory的功能,所以通常不使用BeanFactory。 BeanFactory优点也明显,数据吞吐量和速度是优秀的。 3、Spring BeanFactory容器 Spring有大量对BeanFactory接口的实现,其最常使用的是XmlBeanFactory类。 XmlBeanFactory——功能是读取XML文件的配置数据形成BeanFactory 我们从介绍上也能看出来,XmlBeanFactory的数据来源是XML配置,并且在声明它时需要加载XML文件。 User.java public class User { private String uid; private String uname; public User() { } public User(String uid, String uname) { this.uid = uid; this.uname = uname; } public String getUid() { return uid; } public void setUid(String uid) { this.uid = uid; } public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } @Override public String toString() { return "User{" + "uid='" + uid + '\'' + ", uname='" + uname + '\'' + '}'; } }Main.java public class Main { public static void main(String[] args) { XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("Beans.xml")); User user = (User) factory.getBean("user"); System.out.println(user.toString()); } }Beans.xml bean-id: bean对象的唯一编号 bean-name:bean对象的名称 bean-class:bean注入对象 property-name:注入对象属性名 property-value:注入对象属性值我们需要什么依赖呢? pom.xml org.springframework spring-beans 5.3.18 org.springframework spring-core 5.3.20一定要注意版本兼容问题,会报异常哦~ 输出结果 User{uid='123123', uname='这是我的名字'}4、Spring ApplicationContext容器 Application Context是BeanFacctory的子接口,也称为Spring上下文。可以加载配置文件中定义的bean,在请求状态下分配bean对象。另外增加了企业所需要的功能,例如从属性文件中解析文本和传递事件给监听器。通过context.ApplicationContext 接口定义。加载XML文件的三种方式 FileSystemXmlApplicationContext: 通过扫描XML文件绝对路径进行载入ClassPathXmlApplicationContext: 通过扫描XML文件相对路径进行载入XmlWebApplicationContext: 在一个web应用程序范围内加载XML文件需要ApplicationContext依赖——Spring Context pom.xml org.springframework spring-context 5.3.18要注意版本兼容问题 Main.java public class Main { public static void main(String[] args) { ApplicationContext context = new FileSystemXmlApplicationContext("D:/JavaWebProgram/BeanDemo/src/main/resources/Beans.xml"); User user = (User) context.getBean("user"); System.out.println("绝对路径下的Bean:"+user.toString()); context = new ClassPathXmlApplicationContext("Beans.xml"); user = (User) context.getBean("user"); System.out.println("相对路径下的Bean:"+user.toString()); } }输出结果 绝对路径下的Bean:User{uid='123123', uname='这是我的名字'} 相对路径下的Bean:User{uid='123123', uname='这是我的名字'}5、Spring Bean 5.1 Spring Bean定义 Bean对象是构成应用程序的单元,被Spring IOC容器管理。 Bean定义包含配置元数据。 可以配置什么元数据? Bean的创建Bean的生命周期Bean的依赖关系Bean的属性 属性描述class这个属性是强制性的,并且指定用来创建 bean 的 bean 类。name这个属性指定唯一的 bean 标识符。在基于 XML 的配置元数据中,你可以使用 ID 和/或 name 属性来指定 bean 标识符。scope这个属性指定由特定的 bean 定义创建的对象的作用域,它将会在 bean 作用域的章节中进行讨论。constructor-arg它是用来注入依赖关系的,并会在接下来的章节中进行讨论。properties它是用来注入依赖关系的,并会在接下来的章节中进行讨论。autowiring mode它是用来注入依赖关系的,并会在接下来的章节中进行讨论。lazy-initialization mode延迟初始化的 bean 告诉 IoC 容器在它第一次被请求时,而不是在启动时去创建一个 bean 实例。initialization 方法在 bean 的所有必需的属性被容器设置之后,调用回调方法。它将会在 bean 的生命周期章节中进行讨论。destruction 方法当包含该 bean 的容器被销毁时,使用回调方法。它将会在 bean 的生命周期章节中进行讨论。Bean与Spring容器的关系 步骤1: 扫描XML,扫描注解,配置类获取元数据步骤2: Spring容器定义注册表步骤3: Bean实现类实例化Bean对象,并装载入缓存池中步骤4: 应用程序调取缓存池中的Bean对象![]() Spring配置元数据 有哪些方法可以配置元数据给Spring容器 基于XML的配置文件()基于注解的配置(@Autowire)基于Java的配置(@Configuration)5.2 Spring Bean 作用域 scope有哪些作用域值呢? singleton: Bean以单例模式存在,即getBean时,是同一个Bean对象prototype: Bean以原型模式存在,即getBean时,是不同的Bean对象request: 每次HTTP请求创建新的Bean,仅适用于WebApplicationContext环境session: 同一个Session会话共享一个Bean,不同Session使用不同Bean,仅适用于WebApplicationContext环境global-session: 应用于Portlet应用环境,仅适用于WebApplicationContext环境什么是Portlet? 它是一种基于Java的web组件化网页,看起来有点复古,支持Servlet进行HTTP的请求反馈。 singleton 作用域 singleton是默认作用域,如果你不指定scope,就只有一个Bean对象给你蹂躏。 singleton的创建时间是与容器一同被创建。 Main.java public class Main { public static void main(String[] args) { ApplicationContext context; User user1,user2; context = new ClassPathXmlApplicationContext("Beans.xml"); user1 = (User) context.getBean("user"); System.out.println("user1:"+user1); user1.setUname("真差劲诶"); user2 = (User) context.getBean("user"); System.out.println("user2:"+ user2); } }输出结果 user1:User{uid='123123', uname='这是我的名字'} user2:User{uid='123123', uname='真差劲诶'}我们可以看到,在user1的set方法后,获取到的user2就是set后的数据,即这个bean是同一个对象。 prototype 作用域 prototype是一个原型模式下作用域,能够对应多实例,可以类比父类,getBean出来的则是一个它的子类,每一次get都是不同的子类。 我们在刚刚的程序文件上,只改动scope的值 输出结果 user1:User{uid='123123', uname='这是我的名字'} user2:User{uid='123123', uname='这是我的名字'}我们可以清晰的知道,它们是两个不同的对象,所以才不会受到user1对象的set方法影响。 5.3 Spring Bean 生命周期 Bean的定义Bean的初始化Bean的使用Bean的销毁两种重要生命周期 init-method:调取初始化方法 destroy-method:调取销毁方法初始化回调与销毁回调 InitalizingBean接口实现初始化回调方法 DestroyBean接口实现销毁回调方法 User.java package org.example.POJO; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; /** * 包名:BeanDemo * 作者:章恩光 * 时间:2023/3/5 22:09 周日 */ public class User implements InitializingBean, DisposableBean { private String uid; private String uname; public User() { } public User(String uid, String uname) { this.uid = uid; this.uname = uname; } public String getUid() { return uid; } public void setUid(String uid) { this.uid = uid; } public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public void init(){ System.out.println("Bean is going through init"); } public void destroy(){ System.out.println("Bean will destroy now"); } @Override public String toString() { return "User{" + "uid='" + uid + '\'' + ", uname='" + uname + '\'' + '}'; } @Override public void afterPropertiesSet() throws Exception { System.out.println("UserBean has created。"); } }Beans.xml Spring容器执行顺序: 步骤1: 注入对象实现InitializingBean, DisposableBean接口,需要编写的方法有init(),destroy(),afterPrepartiesSet()步骤2:提供默认初始化和销毁方法 5.4 Spring Bean 后置处理器 什么是Bean 后置处理器? Bean的拓展坞,在初始化前后进行处理 怎么实现后置处理器? BeanPostProcessor接口定义回调方法 可以用该方法进行优化Spring容器启动效率,例如编写自己的实例化逻辑,依赖解析逻辑;可以在Spring容器中插入若干个BeanPostProcessor实现实例化,配置和初始化一个bean之后实现自定义逻辑回调方法;可以配置多个BeanPostProcessor接口,通过设置BeanPostProcessor.Ordered接口提供的order属性来控制BeanPostProcessor顺序。注意: Application自动检测后置处理器实现的bean,再通过容器创建bean。自定义接口实现类中,必须实现的方法: BeanPostProcessor.postProcessBeforeInitialization(Object, String) BeanPostProcessor.postProcessAfterInitialization(Object, String)初始化类InitUser.java public class InitUser implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("AfterInitialization:"+beanName); return bean; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("BeforeInitialization:"+beanName); return bean; } }Beans.xml 加载初始化后置处理器输出结果 BeforeInitialization:user UserBean has created。 Bean is going through init AfterInitialization:user username:这是我的名字执行过程顺序: 后置器BeforeInitialization执行Bean注册表创建Bean执行init()方法后置器AfterInitialization执行使用BeanBean执行destroy()方法5.5 Spring Bean 定义继承 bean定义可以包含很多配置信息:包括构造函数参数,属性值,初始化方法,静态工厂方法名等等 继承bean可以重写值,或添加值。 它们之间的关系:与抽象类继承类的关系相同。 Bean 定义模板 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |